
/*
*********************************
	  SF2D Engine
*********************************

	By Julian Williams
	October 18, 2010
**********************************

	Description:

		Projectile type Entity 
***********************************
*/

#include <SFML/Graphics.hpp>
#include <iostream>
using namespace std;

#include "app.h" //need reference to render window, will get rid of this dependency later.
#include "physics_world.h"
#include "script_engine.h"
#include "image_manager.h"
#include "cfg_reader.h"
#include "helper.h"

#include "projectile.h"





//a private copy function so that i don't have to
//copy/paste the copy constructor to the
//equal operator
void Projectile::copyEntity( const Entity *e)
{
	
	Projectile  *e_copy = (Projectile *)e;
	Entity::copyEntity(e);


	img = e_copy->img;
	


	hasDriver = false;
}//EoF


Projectile ::Projectile ()
{
	refCount = 1;
	cout << "Called lol?" << endl;
}//EoF


//Copy Constructor
Projectile ::Projectile (const Entity &other)
{

	refCount = 1;
	copyEntity(&other);
	//PrepareSpawn(Map.pathStart);
}//EoF



/************************
  AngelScript functions

 *************************/

//Register sheeit

bool Projectile ::Register_With_ScriptEngine()
{

	int r = 0;
	/*
	//Register Properties
		r = aScriptEngine.GetEngine()->RegisterObjectMethod("Entity", "void SetGunAngle(float)", asFUNCTION( Projectile _SetGunAngle), asCALL_CDECL_OBJFIRST);				assert( r >= 0 );
		r = aScriptEngine.GetEngine()->RegisterObjectMethod("Entity", "void RotateGun(float)", asFUNCTION( Projectile _RotateGun), asCALL_CDECL_OBJFIRST);		assert( r >= 0 );

		r = aScriptEngine.GetEngine()->RegisterObjectProperty("Entity", "Entity target",		offsetof(Projectile , target));	;		assert( r >= 0 );
		
		*/
		//Error check
		if( r < 0) 
		{ 
			cout << "[Projectile ] - failed to register script interface. \n";
			return false; 
		}

		return true;
}//EoF



//Prepare Spawn
void Projectile::PrepareSpawn(const b2Vec2 &start)
{
	Entity::PrepareSpawn(start);

	
	//Physics things
	bodyDef.position = METERS_PER_PIXEL * start;
	bodyDef.userData = (void*)(this);
	body = physicsManager.world->CreateBody( &bodyDef );
	fixtureDef.shape = &shapeDef;
	body->CreateFixture( &fixtureDef  );
	

	//cout << body->GetPosition().x << ", " << body->GetPosition().y << endl;


	//Setup Images
	SetImage( *img );
	
	
}//EoF




void Projectile::OnCollision(const Entity *other_body)
{
	//Entity* ob = (Entity*)other_body->GetUserData();
	if(other_body->type == ET_CREEP)
	{
		MarkRemoval();
	}
}//EoF


void Projectile::Update_Logic(asIScriptContext *context)
{
	Entity::Update_Logic(context);


//	RunScriptDriver(context);

	//Update Graphics to Physics' Engine's Positions
	/*
	sf::Vector2f real_positions;

	real_positions.x = (body->GetPosition().x* PIXELS_PER_METER);
	real_positions.y = (body->GetPosition().y* PIXELS_PER_METER);




	SetPosition( real_positions );

	*/

	if(GetPosition().x < 0 || GetPosition().y < 0 ||
	   GetPosition().x > Map.Get_PixelSize().x || GetPosition().y > Map.Get_PixelSize().y)
	{
		MarkRemoval();
	}
	SetRotation( radiansToDegrees(body->GetAngle()));
	

//Temporary stuff, all this goes to scripts


	//gunSprite.Rotate(5);
}//EoF




void Projectile ::Render(sf::RenderWindow * rendow)
{		
	Entity::Render(rendow);
	
//	rendow->Draw(*this);
}//EoF

/* Get the Ammo Configuration file and load properties */
/* Get the Configuration file and load properties */
bool Projectile::Get_Config(const string& resource_dir)
{

	
	//grab and create the nessisary directories
	string image_location = resource_dir + string("image.png");
	string cfg_location = resource_dir + string("properties.cfg");
	//string script_name = App::getInstance().Resources_Dir["scripts"];
	//string snd_location = folder_location + string("fire.wav");

	cout << "Loading Entity folder: " << resource_dir << endl;
	cout << "Config from: " << cfg_location << endl;
	cout << "Image from: " << image_location << endl;

	//cout << "Gun sound from: " << snd_location << endl;



//Now Grab the firing sound for the gun
	//if(!Load_Sounds(s_fire, SND_fire, snd_location)) { return false; }




//Grab particle Config
		cfg_reader cfg(cfg_location, true);


//Get all of the properties
			type = cfg.Get_Info("info:type", 1);
			name = cfg.Get_Info("info:name", "Default");
			
			damage = cfg.Get_Info("info:damage", 1.0);
			speed = cfg.Get_Info("info:speed", 100);

		//	script_name += cfg.Get_Info("info:script_driver", "NULL");


//Animation related information
			tile_size.x = cfg.Get_Info("animation:tile_width", 32);
			tile_size.y = cfg.Get_Info("animation:tile_height", 32);

			sf::Vector2f origin;
			origin.x = cfg.Get_Info("animation:origin_x",16);
			origin.y = cfg.Get_Info("animation:origin_y",16);
			SetOrigin( origin );
		
			//cout << "Particle Image from: " << image_location << "\n\n";

			//Load Particle Image used for each type
			img = gImageManager.getResource( image_location );
			if(img == NULL) { return false; }
			SetImage( *img );


//Setup Physics
//create the dynamic body
			bodyDef.type = static_cast<b2BodyType> (cfg.Get_Info("physics:body_type", b2_dynamicBody));
			bodyDef.linearDamping = cfg.Get_Info("physics:linear_damping", 20);
			bodyDef.fixedRotation = cfg.Get_Info("physics:fixed_rotation", false);
			bodyDef.bullet = cfg.Get_Info("physics:continues_collision", false);

			//shape of the dynamic body
			shapeDef.SetAsBox(tile_size.x/2*METERS_PER_PIXEL, tile_size.y/2*METERS_PER_PIXEL);
			
			//circle.m_p.Set(50*MPP, 50*MPP);
			circleDef.m_radius = cfg.Get_Info("physics:radius", 16) * METERS_PER_PIXEL;
		
		

			fixtureDef.shape		= &shapeDef;
			
			fixtureDef.filter.categoryBits = 0x0002;
			fixtureDef.filter.maskBits = 0x0004;


			fixtureDef.density		= cfg.Get_Info("physics:density", 1.0);
			fixtureDef.friction		= cfg.Get_Info("physics:friction", 0.3); 
			fixtureDef.restitution	= cfg.Get_Info("physics:bounciness", 0.5);
			fixtureDef.isSensor		= cfg.Get_Info("physics:is_sensor", false);

			//apply the fixture to the body
			//body->CreateFixture(&fixtureDef);

	return true;
}//EoF
